CNC Example 10: Programming Dynamic CNC Paths
See the CNC10_DynamicPath.project
sample project in the installation directory of CODESYS under ..\CODESYS SoftMotion\Examples
.
This example shows how a CNC path can be created directly in the application at runtime – not fed with G code from a CNC program object or a file. When this kind of conventional CNC program is compiled, the path data is stored in a SMC_CNC_Data
data structure type. This internal data is then compiled in specific global data structures depending on the compile mode (SMC_CNC_REF or SMC_OutQueue).
In compile mode SMC_CNC_REF, the data is stored in an array of SMC_GEOINFO
elements. The array in the application code is usually passed to the function block instance SMC_NCDecoder
. At runtime, the data is decoded there and stored in a global data structure of type SMC_OUTQUEUE
. Then path preprocessing function blocks can be called.
In compile mode SMC_OutQueue, a global data structure (SMC_OUTQUEUE
) is generated directly. This data structure in the application code is passed to the interpolator (SMC_Interpolator
FB instance). The function block SMC_NCDecoder
is not called.
In compile mode FILE, the data is stored in a file. The data is stored as an array of elements of type SMC_GEOINFO
and correspond to the data that is generated in compile mode SMC_CNC_REF.
Instead of programming the CNC path, you can program an application code that instantiates a data structure of type SMC_OUTQUEUE
at runtime and assigns its values. You program a CNC path that is generated dynamically at runtime. You can pass the data structure to other function block instances (for example to the path preprocessing function blocks or to the function block SMC_Interpolator
).
Programming
Tip
The CNCDynamicPath
sample project is located in the installation directory of CODESYS. The sample project was developed from the CNConline
project. It includes the Path
program instead of the graphically programmed Example
path. A data structure of type SMC_OUTQUEUE
is generated dynamically.
Declare a data structure of type
SMC_OUTQUEUE
. The data structure contains the CNC path data and is populated dynamically.Example:
QUEUE
Allocate memory for the path with the required amount to
SMC_GEOINFO
elements.Example:
BUF
Declare a variable of type
SMC_GEOINFO
with an initial step.Example:
GEO
An array element of data type
SMC_GEOINFO
corresponds to a path element in the CNC code. The following steps have to be performed for each element in order to add the element to theSMC_OUTQUEUE
:Every array element has a start position that corresponds to the end position of the previous array element.
Example:
GEO.piStartPos.dX := 0;
orGEO.piStartPos := GEO.piDestPos;
Determine a movement type for each array element.
Example:
GEO.iMoveType := CCLW;
orGEO.iMoveType := LIN;
Set the parameters of the movement type. This is not required for all movement types.
Example: For an arc (movement type: CCLW), setting the following positions is required:
geoinfo_A[i].dP1 := 200; geoinfo_A[i].dP2 := 100; geoinfo_A[i].dP3 := 50; geoinfo_A[i].dT1 := 0; geoinfo_A[i].dT2 := 90;
Insert the calculation of the end position.
SMC_CalcEndPnt(ADR(GEO));
Insert the calculation of the object length.
SMC_CalcLengthGeo(ADR(GEO));
Save the object in
QUEUE
:SMC_AppendObj(POQ:=ADR(QUEUE), PGI:=ADR(GEO));
When the path is created completely, the end markers have to be set: QUEUE.bEndOfList := TRUE;
Tip
Then, when a path preprocessing function block is called, it is required to set the start or end bit for InternMark
.
CNC path with two path elements
In this example, the arrays are not defined with the X/Y-positions. If this should be an example with two path elements as described, then these arrays would have to have two elements each.
For example, derived from the sample project:
xp:ARRAY[1..2] OF REAL:= [100,50]; yp:ARRAY[1..2] OF REAL:= [0,100];
PROGRAM Path VAR iState : INT; QUEUE : SMC_OUTQUEUE; BUF : ARRAY[0..49] OF SMC_GEOINFO; // Memory allocation GEO : SMC_GEOINFO:=(dT1:=0, dT2:=1, dToolRadius:=0, dVel:=100, dVel_End:=100, dAccel:=200, dDecel:=500, iObj_Nr:=0); // Initial path element n : INT := 0; QUEUE.nSize := SIZEOF(BUF); END_VAR CASE iState OF 0: QUEUE.pbyBuffer := ADR(BUF[0]); // Initialize QUEUE SMC_SetQueueCapacity(ADR(QUEUE), SIZEOF(BUF)); iState := iState + 1; 1: // Fill QUEUE WHILE NOT QUEUE.bFull DO // When QUEUE is full, wait until it has been processed by the following FBs n := n + 1; GEO.iSourceLine_No := n; GEO.piStartPos := GEO.piDestPos; // Copying last destination GEO.iMoveType := LIN; // Generating linear movement GEO.iObjNo := GEO.iObjNo + 1; // Calculating number GEO.piDestPos.dX := xp[n]; // Generatint position GEO.piDestPos.dY := yp[n]; SMC_CalcLengthGeo(pg := ADR(GEO)); // Calculating length of object with the help of the standard function SMC_AppendObj(poq:=ADR(QUEUE), pgi:=ADR(GEO)); // Appending object to QUEUE IF n = SIZEOF(xp)/SIZEOF(xp[1]) THEN // All target positions processed QUEUE.bEndOfList := TRUE; n := 0; iState := 2; EXIT; END_IF END_WHILE 2: //Done ; END_CASE CheckVel(bExecute:=TRUE , poqDataIn:=ADR(queue)); // Preprocessing
Important
If the SMC_OUTQUEUE
data structure is populated with SMC_GEOINFO
data and the data structure element was set to bFULL = TRUE
, then we do not recommend a further assignment of SMC_GEOINFO
data. In this case, the creation of the path is interrupted at runtime until the first element of the SMC_OUTQUEUE
data structure is processed in the interpolator. Only then is another element inserted.
Avoid this interruption by allocating enough memory. See variable BUF
.
Important
If the data structure SMC_OUTQUEUE
is refilled after the first execution, then the interpolator and all preprocessing function blocks (example: SMC_CheckVelocities
) have to be restarted by a rising edge at Execute
.